/*
 * Copyright 2007-2008 Brian Cavalier
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package  org.bc.iterate;

/**
 * Tests if Objects are between (inclusive low, exclusive high) the two
 * supplied {@link Comparable}s.
 * 
 * @author Brian Cavalier
 * @see Test
 * @see  Comparable
 */
public class Range<T> implements Test<T>, Comparable<T>{
	private Comparable<T> _low;
	private Comparable<T> _high;
	
	/**
	 * Create a range that includes all Objects greater or equal to low, and
	 * less than high.
	 *
	 * @param low Inclusive lower bound
	 * @param high Exclusive upper bound
	 */
	public Range(Comparable<T> low, Comparable<T> high) {
		setLow(low);
		setHigh(high);
	}
	
	public boolean go(T item) {
		return (compareTo(item) == 0);
	}

    /**
     * @return <ul><li>0 if <code>low <= item < high</code><li>
     * <li>-1 if <code>item < low</code></li>
     * <li> 1 if <code> item >= high </code></li>
     */
    public int compareTo(T item) {
		int result = 0;
		if(getLow().compareTo(item) > 0) {
			result = -1;
		}
		else if(getHigh().compareTo(item) <= 0) {
			result = 1;
		}
		return result;
	}

    public void set(Comparable<T> low, Comparable<T> high)
    {
        setLow(low);
        setHigh(high);
    }

    public Comparable<T> getLow()
    {
        return _low;
    }

    public void setLow(Comparable<T> _low)
    {
        this._low = _low;
    }

    public Comparable<T> getHigh()
    {
        return _high;
    }

    public void setHigh(Comparable<T> _high)
    {
        this._high = _high;
    }

    public boolean equals(Object o)
    {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Range)) {
            return false;
        }

        Range range = (Range) o;

        if (_high != null ? !_high.equals(range._high) : range._high != null) {
            return false;
        }
        if (_low != null ? !_low.equals(range._low) : range._low != null) {
            return false;
        }

        return true;
    }

    public int hashCode()
    {
        int result = (_low != null ? _low.hashCode() : 0);
        result = 31 * result + (_high != null ? _high.hashCode() : 0);
        return result;
    }
}